home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 130_01 / makehex.c < prev    next >
Text File  |  1985-03-09  |  6KB  |  309 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6. /*
  7.     This is the part of the program which con-
  8.     tains routines for reading Intel standard
  9.     HEX files (used by the CP/M assembler and
  10.     many others). These routines will also re-
  11.     cognize HEX record types which is not used
  12.     by the CP/M assembler but will ignore them
  13.     and print a message on the console device.
  14.     
  15.             (c) 1981 Jan Larsson.
  16. */
  17.  
  18.  
  19. #include "bdscio.h"
  20. #include "makedef.h"
  21.  
  22.  
  23. rhex( name, p, max, cmp, real )
  24. char *name, *p ;
  25. int max ;
  26. unsigned cmp ;
  27. int real ;
  28. {
  29.     int c, total ;
  30.     unsigned oadress ;
  31.     char *p2, n, type, bytes, buf[BUFSIZ], first ;
  32.     char *pp ;
  33.     char chk ;
  34.     unsigned adress, fd ;
  35.  
  36.     fd = fopen( name, buf );
  37.     if(fd == ERROR)error(24);
  38.     total = 0 ; first = TRUE ;
  39.     skiplf( buf );
  40.     while((c = getc( buf )) != CPMEOF && c != ERROR){
  41.         bytes = getbyte( buf );
  42.         chk = bytes ;
  43.         if(first == TRUE);else oadress = adress ;
  44.         adress = getword( buf );
  45.         if(first == TRUE);else p = p2 + (adress - oadress);
  46.         chk += (adress & 0x00ff);
  47.         chk += ((adress >> 8) & 0x00ff);
  48.         if(first == TRUE){
  49.             if(cmp != adress && cmp != 0)
  50.                 cont( cmp, adress );
  51.             first = FALSE ;
  52.             }
  53.         if(sbrk( bytes ) == ERROR)error(20);
  54.         type = getbyte( buf );
  55.         chk += type ;
  56.         switch (type) {
  57.           case 0 :
  58.             p2 = p ;
  59.             for(n = 0 ; n < bytes ; n++ ){
  60.                 *p = getbyte( buf );
  61.                 chk += *p++ ;
  62.                 }
  63.             chk += getbyte(buf);
  64.             if(chk == 0)total += bytes ;
  65.             else {
  66.                 printf("Checksum error at adress %4x",adress );
  67.                 printf("\nrecord ignored." );
  68.                 printf("\nChecksum = %x.\n",chk);
  69.                 p = p2 ;
  70.                  }
  71.             skiplf( buf );
  72.             break ;
  73.           case 1 :
  74.             fabort( fd );
  75.             return( total );
  76.             break ;
  77.           case 2 : 
  78.             printf("INTERNAL SYMBOL RECORD found at adress ");
  79.             printf("%4x, ignored. \n", adress );
  80.             skiplf( buf );
  81.             break ;
  82.           case 3 : 
  83.             printf("No processing of EXTERNAL SYMBOL RECORDS ");
  84.             printf(", found one at adress %4x \n", adress );
  85.             skiplf( buf );
  86.             break ;
  87.           case 4 :
  88.             printf("RELOCATION INFORMATION RECORD found at ");
  89.             printf("adress %4x, ignored.\n",adress );
  90.             skiplf( buf );
  91.             break ;
  92.           case 5 :
  93.             printf("Ignoring a MODULE DEFINITION RECORD at ");
  94.             printf("adress %4x.\n",adress );
  95.             skiplf( buf );
  96.             break ;
  97.           default :
  98.             printf("I'm ignoring an unknown HEX record type ");
  99.             printf("at adress %4x.\n", adress );
  100.             skiplf( buf );
  101.             break ;
  102.           }
  103.         }
  104.     if(bytes > 0){
  105.     printf("%s was a strange HEX file, I couldn't find the ", name );
  106.     printf("EOF record.\n");
  107.     printf("I have read %d number of bytes successfully (I hope) and\n",total);
  108.     printf("the latest adress was %4x.\n",adress );
  109.         }
  110.     fabort( fd );
  111.     return(total);
  112. }
  113.  
  114.  
  115.  
  116.  
  117.  
  118. /*
  119.     The following function returns a word from
  120.     four HEX characters in a file.
  121. */
  122.  
  123. unsigned getword( buf )
  124. char *buf ;
  125. {
  126.     return((getbyte( buf ) << 8) | getbyte( buf ));
  127. }
  128.  
  129.  
  130.  
  131. /*
  132.     Here's the function which returns a byte 
  133.     from two HEX characters.
  134. */
  135.  
  136. getbyte( buf )
  137. char *buf ;
  138. {
  139.     return((gethex( buf ) << 4) | gethex( buf ));
  140. }
  141.  
  142.  
  143.  
  144.  
  145. /*
  146.     Finally the real workhorse which reads a
  147.     HEX character from the file and returns
  148.     it's binary value. If we find an EOF in
  149.     this routine we might as well quit as there
  150.     must be some serious error.
  151. */
  152.  
  153. gethex( buf )
  154. char *buf ;
  155. {
  156.     int c ;
  157.  
  158.     c = tolower( getc( buf ) );
  159.     if(c == CPMEOF || c == ERROR)error(21);
  160.     if(c >= '0' && c <= '9')
  161.             return(c - '0');
  162.     else if(c >= 'a' && c <= 'f')
  163.             return((c - 'a') + 10);
  164.     else error(22);
  165. }
  166.  
  167.  
  168. /*
  169.     A small function whose only purpose is to
  170.     skip to EOL.
  171. */
  172.  
  173. skiplf( buf )
  174. char *buf ;
  175. {
  176.     int c ;
  177.  
  178.     c = getc( buf );
  179.     while(c == 0x0d || c == '\n' || c == ' ')c = getc( buf );
  180.     ungetc( c, buf );
  181. }
  182.  
  183.  
  184.  
  185.  
  186. /*
  187.     To this fonction we come when we are trying
  188.     to read in a bios with a start adress which 
  189.     doesn't match the CP/M we are patching it
  190.     together with.
  191. */
  192.  
  193. cont( cmp, adress )
  194. unsigned cmp, adress ;
  195. {
  196.     printf("What are you trying to do ??? Your CP/M wants the BIOS at \n");
  197.     printf("adress %x and you want me to patch in a BIOS which starts\n",cmp);
  198.     printf("at %x, want to continue (y/n) ? ", adress );;
  199.     if(tolower(getchar()) == 'y')return ;
  200.     else exit();
  201. }
  202.  
  203.  
  204.  
  205.  
  206.  
  207. rcpm( cpmfile, base )
  208. char *cpmfile, *base ;
  209. {
  210.     char n ;
  211.     unsigned fdcpm ;
  212.  
  213.     if((fdcpm=open(cpmfile,0)) == ERROR){
  214.         printf("Sorry, cannot open %s as cpmfile.\n",cpmfile);
  215.         exit();
  216.         }
  217.     for(n = 0 ; n < 16 ; n++ )
  218.     if(read( fdcpm, base, 1 ) == ERROR){
  219.         printf("Uuuuhhh !!!  Error when reading %s, I give up.\n",cpmfile);
  220.         exit();
  221.         }
  222.     for(n = 0 ; n < 51 ; n++ )
  223.     if(read( fdcpm, base, 1) == ERROR){
  224.         printf("Error occured while reading %s so I'm quitting.\n",cpmfile);
  225.         exit();
  226.         }
  227.     else base += 128 ;
  228.     fabort( fdcpm );
  229. }
  230.  
  231.  
  232.  
  233.  
  234. wcpm( cpmfile, base, size )
  235. char *cpmfile, *base ;
  236. int size ;
  237. {
  238.     unsigned fdcpm ;
  239.     char n ;
  240.  
  241.     if((fdcpm=open(cpmfile,1)) == ERROR){
  242.         printf("Can't open %s for output, unfortunately.\n",cpmfile);
  243.         exit();
  244.         }
  245.     for( n = 0 ; n < 16 ; n++ )
  246.     if(write( fdcpm, base, 1 ) == ERROR){
  247.         printf("Disk write error when writing %s.\n",cpmfile);
  248.         exit();
  249.         }
  250.     for( n = 0 ; n < size ; n++ )
  251.     if(write( fdcpm, base, 1 ) == ERROR){
  252.         printf("Write error on %s, maybe lack of disk space ?\n",cpmfile);
  253.         exit();
  254.         }
  255.     else base += 128 ;
  256.     if(close( fdcpm ) == ERROR){
  257.         printf("Oh nooo...  can't close %s. \n",cpmfile);
  258.         exit();
  259.         }
  260. }
  261.  
  262.  
  263.  
  264.  
  265. sysgen( drive, base )
  266. int drive ;
  267. char *base ;
  268. {
  269.     int cdrive, sector, track ;
  270.  
  271.     cdrive = bdos( 25 );
  272.     bdos( 14, drive );
  273.  
  274.     for( track = 0 ; track < 2 ; track++ ){
  275.         for( sector = 1 ; sector <= 26 ; sector++ ){
  276.             bios( 10, track );
  277.             bios( 11, skew(sector) );
  278.             bios(12,base + (((track*26) + (skew(sector) - 1)) * 128));
  279.             bios(14);
  280.             }
  281.         }
  282.     bdos( 14, cdrive );
  283. }
  284.  
  285.  
  286.  
  287. skew( sector )
  288. int sector ;
  289. {
  290.     char skewtab[27];
  291.  
  292.     initb(skewtab,"1,7,13,19,25,5,11,17,23,3,9,15,21,2,8,14,20,26,6,12,18,24,4,10,16,22");
  293.  
  294.     sector-- ;
  295.     return( skewtab[ sector ] );
  296. }
  297.  
  298.  
  299.  
  300.  
  301.  
  302. error( type )
  303. char type ;
  304. {
  305.     printf("Error of type %u occured.\n",type);
  306. }
  307.  
  308.  
  309.